#include "DrawWidget.h"

CDrawWidget::CDrawWidget(QWidget* parent) : QOpenGLWidget(parent)
{

    m_pSystemData = CSystemData::GetSystemData();

    m_bLBtnClicked = false;
    m_RotateType   = RotateType::Rotate_0;
    m_ShapeType    = ShapeType::Shape_Unknown;

    m_BlackPen.setColor(QColor(0,0,0));
    m_BlackPen.setWidth(2);

    m_RadPen.setColor(QColor(255,0,0));
    m_RadPen.setWidth(2);

    m_BluePen.setColor(QColor(30,144,255));
    m_BluePen.setWidth(2);

    m_TextFont.setFamily(QStringLiteral("楷体"));
    m_TextFont.setPixelSize(20);
    m_WhiteBrush.setColor(QColor(255,255,255));
    m_WhiteBrush.setStyle(Qt::BrushStyle::SolidPattern);
    m_NullBrush.setStyle(Qt::BrushStyle::NoBrush);
}

    CDrawWidget::~CDrawWidget()
{

}

void CDrawWidget::paintEvent(QPaintEvent* event)
{
    QOpenGLWidget::paintEvent(event);
    QPainter painter(this);
    painter.setBrush(m_WhiteBrush);
    painter.drawRect(rect());


    switch(m_PenColor)
    {
    case PenColor::Color_Black:
        painter.setPen(m_BlackPen);
        break;
    case PenColor::Color_Rad:
        painter.setPen(m_RadPen);
        break;
    case PenColor::Color_Blue:
        painter.setPen(m_BluePen);
        break;
    default:
        break;
    }
    painter.setFont(m_TextFont);
    painter.setBrush(m_NullBrush);

    switch(m_RotateType)
    {
    case RotateType::Rotate_0:
    {
        break;
    }
    case RotateType::Rotate_90:
    {
        painter.translate(width(),0.0);
        painter.rotate(90);
        break;
    }
    case RotateType::Rotate_180:
    {
        painter.translate(width(),height());
        painter.rotate(180);
        break;
    }
    case RotateType::Rotate_270:
    {
        painter.translate(0.0, height());
        painter.rotate(270);
        break;
    }

    }


    int iSize = m_pSystemData->m_ShapeVec.size();
    for(int i = 0; i < iSize ; i++)
    {
        CShapeData* pShape = m_pSystemData->m_ShapeVec.at(i);
        switch (pShape->GetShapeType())
        {
        case ShapeType::Shape_Rectangle:
        {
            CRectangleData* pRectangle = static_cast<CRectangleData*>(pShape);
            painter.drawRect(QRectF(pRectangle->GetStartPosX(),pRectangle->GetStartPosY(),pRectangle->GetWidth(),pRectangle->GetHeight()));
            break;
        }
        case ShapeType::Shape_Ellipse:
        {
            CEllipseData* pEllipse = static_cast<CEllipseData*>(pShape);
            painter.drawEllipse(QRectF(pEllipse->GetStartPosX(),pEllipse->GetStartPosY(),pEllipse->GetRadiusW(),pEllipse->GetRadiusH()));
            break;
        }
        case ShapeType::Shape_Triangle:
        {
            CTriangleData* pTriangle = static_cast<CTriangleData*>(pShape);
            QPoint p1(pTriangle->GetStartPosX(), pTriangle->GetStartPosY());
            QPoint p2(pTriangle->GetStartPosX() + qAbs(pTriangle->GetWidth()), pTriangle->GetStartPosY());
            QPoint p3(pTriangle->GetStartPosX() + qAbs(pTriangle->GetWidth())/2.0, pTriangle->GetStartPosY()-qAbs(pTriangle->GetHeight()));
            painter.drawLine(p1, p2);
            painter.drawLine(p1, p3);
            painter.drawLine(p2, p3);
            break;
        }
        case ShapeType::Shape_Line:
        {
            CLineData* pLine = static_cast<CLineData*>(pShape);
            painter.drawLine(QLineF(pLine->GetStartPosX(),pLine->GetStartPosY(),pLine->GetEndPosX(),pLine->GetEndPosY()));
            break;
        }
        case ShapeType::Shape_Pentagon:
        {
            CPentagonData* pPentagon = static_cast<CPentagonData*>(pShape);
            QPoint p1(pPentagon->GetStartPosX(), pPentagon->GetStartPosY());
            QPoint p2(pPentagon->GetStartPosX() + qAbs(pPentagon->GetWidth()), pPentagon->GetStartPosY());

            QPoint p3(pPentagon->GetStartPosX() + (3*qAbs(pPentagon->GetWidth()))/2.0, pPentagon->GetStartPosY()-sqrt(3)*qAbs(pPentagon->GetHeight())/2.0);
            QPoint p4(pPentagon->GetStartPosX() - (qAbs(pPentagon->GetWidth()))/2.0  , pPentagon->GetStartPosY()-sqrt(3)*qAbs(pPentagon->GetHeight())/2.0);
            QPoint p5(pPentagon->GetStartPosX() + (qAbs(pPentagon->GetWidth()))/2.0  , pPentagon->GetStartPosY()-2*sqrt(3)*qAbs(pPentagon->GetHeight())/2.0);

            painter.drawLine(p1, p2);
            painter.drawLine(p5, p3);
            painter.drawLine(p2, p3);
            painter.drawLine(p4, p5);
            painter.drawLine(p1, p4);
            break;
        }
        default:
        {
            break;
        }
        }
    }


    if (m_bLBtnClicked)
    {
        switch (m_ShapeType)
        {
        case ShapeType::Shape_Rectangle:
        {
            painter.drawRect(QRect(m_ClickPoint, m_MovePoint));
            break;
        }
        case ShapeType::Shape_Ellipse:
        {
            painter.drawRect(QRect(m_ClickPoint, m_MovePoint));
            break;
        }
        case ShapeType::Shape_Triangle:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() > m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();


            QPoint dis = m_MovePoint - m_ClickPoint;
            QPoint p1(iX1, iY1);
            QPoint p2(iX1 + qAbs(dis.x()), iY1);
            QPoint p3(iX1 + qAbs(dis.x())/2.0, iY1-qAbs(dis.y()));
                painter.drawLine(p1, p2);
                painter.drawLine(p1, p3);
                painter.drawLine(p2, p3);
                break;
        }
        case ShapeType::Shape_Line:
        {
            painter.drawLine(m_ClickPoint, m_MovePoint);
            break;
        }
        case ShapeType::Shape_Pentagon:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() > m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();


            QPoint dis = m_MovePoint - m_ClickPoint;
            QPoint p1(iX1, iY1);
            QPoint p2(iX1 + qAbs(dis.x())        , iY1);
            QPoint p3(iX1 + (3*qAbs(dis.x()))/2.0, iY1-sqrt(3)*qAbs(dis.y())/2.0);
            QPoint p4(iX1 - (qAbs(dis.x()))/2.0  , iY1-sqrt(3)*qAbs(dis.y())/2.0);
            QPoint p5(iX1 + (qAbs(dis.x()))/2.0  , iY1-2*sqrt(3)*qAbs(dis.y())/2.0);


            painter.drawLine(p1, p2);
            painter.drawLine(p5, p3);
            painter.drawLine(p2, p3);
            painter.drawLine(p4, p5);
            painter.drawLine(p1, p4);
            break;
        }
        default:
        {
            break;
        }
        }
    }

    //TODO(...):进行数据的渲染、绘画
}

void CDrawWidget::resizeEvent(QResizeEvent* event)
{
    QOpenGLWidget::resizeEvent(event);
}
void CDrawWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(m_bLBtnClicked)
    {
        m_MovePoint = event->pos();
        update();
    }
    QOpenGLWidget::mouseMoveEvent(event);
}

void CDrawWidget::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::MouseButton::LeftButton)
    {
        m_bLBtnClicked = true;
        m_ClickPoint = event->pos();
    }
    QOpenGLWidget::mousePressEvent(event);
}

void CDrawWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::MouseButton::LeftButton)
    {
        m_bLBtnClicked =false;
        m_MovePoint = event->pos();
        switch(m_ShapeType)
        {
        case ShapeType::Shape_Rectangle:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() < m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();


            QPoint dis = m_MovePoint - m_ClickPoint;
            CRectangleData* pRectangle = new CRectangleData(double(iX1),double(iY1),qAbs(double(dis.x())),qAbs(double(dis.y())));
            m_pSystemData->m_ShapeVec.push_back(pRectangle);
                update();
            break;
        }
        case ShapeType::Shape_Ellipse:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() < m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();


            QPoint dis = m_MovePoint - m_ClickPoint;
            CEllipseData* pEllipse = new CEllipseData(double(iX1),double(iY1),qAbs(double(dis.x())),qAbs(double(dis.y())));
            m_pSystemData->m_ShapeVec.push_back(pEllipse);
            update();
            break;
        }
        case ShapeType::Shape_Triangle:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() > m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();

            QPoint dis = m_MovePoint - m_ClickPoint;
            CTriangleData* pTriangle = new CTriangleData(double(iX1),double(iY1),qAbs(double(dis.x())),qAbs(double(dis.y())));
            m_pSystemData->m_ShapeVec.push_back(pTriangle);
            update();
            break;
        }
        case ShapeType::Shape_Line:
        {
            int iX1 = m_ClickPoint.x();
            int iY1 = m_ClickPoint.y();
            int iX2 = m_MovePoint.x();
            int iY2 = m_MovePoint.y();

            CLineData* pLine = new CLineData(double(iX1),double(iY1),double(iX2),double(iY2));
            m_pSystemData->m_ShapeVec.push_back(pLine);
            update();
            break;
        }
        case ShapeType::Shape_Pentagon:
        {
            int iX1 = m_ClickPoint.x() < m_MovePoint.x()?m_ClickPoint.x():m_MovePoint.x();
            int iY1 = m_ClickPoint.y() > m_MovePoint.y()?m_ClickPoint.y():m_MovePoint.y();

            QPoint dis = m_MovePoint - m_ClickPoint;
            CPentagonData* pPentagon = new CPentagonData(double(iX1),double(iY1),qAbs(double(dis.x())),qAbs(double(dis.y())));
            m_pSystemData->m_ShapeVec.push_back(pPentagon);
            update();
            break;
        }
        default:
        {
            break;
        }
        }
    }
    QOpenGLWidget::mouseReleaseEvent(event);
}


int CDrawWidget::RotateLeft()
{
    switch(m_RotateType)
    {
    case RotateType::Rotate_90:
    {
        m_RotateType = RotateType::Rotate_0;
        break;
    }
    case RotateType::Rotate_180:
    {
        m_RotateType = RotateType::Rotate_90;
        break;
    }
    case RotateType::Rotate_270:
    {
        m_RotateType = RotateType::Rotate_180;
        break;
    }
    default:
    {
        m_RotateType = RotateType::Rotate_270;
    }
    }


    update();
    return NORMAL_RETURN;
}

int CDrawWidget::RotateRight()
{
    switch(m_RotateType)
    {
    case RotateType::Rotate_90:
    {
        m_RotateType = RotateType::Rotate_180;
        break;
    }
    case RotateType::Rotate_180:
    {
        m_RotateType = RotateType::Rotate_270;
        break;
    }
    case RotateType::Rotate_270:
    {
        m_RotateType = RotateType::Rotate_0;
        break;
    }
    default:
    {
        m_RotateType = RotateType::Rotate_90;
    }
    }


    update();
    return NORMAL_RETURN;
}
